<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>3.添加相机用透视原理进行投影-3D绘图标准模型-OGL图形库</title>
    <style>
        canvas{
            border:1px solid #aaa;
            margin: 0 auto;
            display: block;
        }
    </style>
</head>
<body>
    <canvas width="554" height="554"></canvas>

    <script type="module">
        import { Renderer, Camera, Transform, Sphere, Box, Cylinder, Torus, Program, Mesh } from '/common/lib/ogl/index.mjs';

        let canvas = document.querySelector("canvas");

        // 1. 创建画布宽高512的renderer对象
        const renderer = new Renderer({
            canvas,
            width:512,
            height:512,
        });

        const gl = renderer.gl;
        gl.clearColor(1, 1, 1, 1);
        // 2. 创建相机（默认透视投影）
        // 视角35°
        const camera = new Camera(gl, { fov:35 });
        // 相机的位置
        camera.position.set(0, 1, 7);
        // 相机的朝向
        camera.lookAt([0, 0, 0]);

        // 3. 创建场景
        const scene = new Transform();

        // 4. 创建几何体对象
        const sphereGeometry = new Sphere(gl); // 球体
        const cubeGeometry = new Box(gl); // 立方体
        const cylinderGeometry = new Cylinder(gl); // 椎体
        const torusGeometry = new Torus(gl); // 环面

        // 5. 创建webgl程序
        const vertex = /* glsl */ `
            precision highp float;

            attribute vec3 position;
            attribute vec3 normal;

            uniform mat4 modelViewMatrix;
            uniform mat4 projectionMatrix;
            uniform mat3 normalMatrix;

            varying vec3 vNormal;

            void main() {
                vNormal = normalize(normalMatrix * normal);
                gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
            }
        `;

        const fragment = /* glsl */ `
            precision highp float;

            varying vec3 vNormal;

            void main() {
                vec3 normal = normalize(vNormal);
                float lighting = dot(normal, normalize(vec3(-0.3, 0.8, 0.6)));
                gl_FragColor.rgb = vec3(0.2, 0.8, 1.0) + lighting * 0.1;
                gl_FragColor.a = 1.0;
            }
        `;

        const program = new Program(gl, {
            vertex,
            fragment,
        });

        // 6. 创建网格对象
        const torus = new Mesh(gl, {geometry: torusGeometry, program});
        torus.position.set(0, 1.3, 0);
        torus.setParent(scene);

        const sphere = new Mesh(gl, {geometry: sphereGeometry, program});
        sphere.position.set(1.3, 0, 0);
        sphere.setParent(scene);

        const cube = new Mesh(gl, {geometry: cubeGeometry, program});
        cube.position.set(0, -1.3, 0);
        cube.setParent(scene);

        const cylinder = new Mesh(gl, {geometry: cylinderGeometry, program});
        cylinder.position.set(-1.3, 0, 0);
        cylinder.setParent(scene);

        // 7. 渲染
        requestAnimationFrame(update);
        function update() {
            requestAnimationFrame(update);

            torus.rotation.y -= 0.02;
            sphere.rotation.y -= 0.03;
            cube.rotation.y -= 0.04;
            cylinder.rotation.y -= 0.02;

            renderer.render({scene, camera});
        }

    </script>
</body>
</html>